package com.spring.calc.Controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

@RestController
@RequestMapping("/calc")
public class CalcController {
    public List<String> expressionList = new ArrayList<>();

    @RequestMapping("/getlist")
    public List<String> getlist(){
        return expressionList;
    }

    @RequestMapping("/deletelist")
    public boolean deleteList(){
        long n = expressionList.size();
        for (int i = 0; i < n; i++) {
            expressionList.remove(i);
        }
        return true;
    }

    @RequestMapping("/get")
    public float calc(String expreString) {
        // 更严格的空白字符处理
        System.out.println(expreString);
        String expression = expreString.replaceAll("\\s+", "").trim();

        if (expression.isEmpty()) {
            throw new IllegalArgumentException("表达式不能为空");
        }

        try {
            double result = evaluateExpression(expression);
            expressionList.add(expression+"="+result);
            System.out.println(result);
            System.out.println(expressionList);
            // 四舍五入保留两位小数
            return (float) (Math.round(result * 100) / 100.0);
        } catch (Exception e) {
            throw new IllegalArgumentException("表达式计算错误: " + expreString + " 原因: " + e.getMessage());
        }
    }

    private double evaluateExpression(String expression) {
        Stack<Double> numbers = new Stack<>();
        Stack<Character> operators = new Stack<>();
        int i = 0;
        int n = expression.length();

        while (i < n) {
            char c = expression.charAt(i);

            // 跳过空格(虽然前面已经处理过，但保留作为二次保障)
            if (c == ' ') {
                i++;
                continue;
            }

            // 处理数字
            if (Character.isDigit(c)) {
                StringBuilder numStr = new StringBuilder();
                // 读取连续数字
                while (i < n && Character.isDigit(expression.charAt(i))) {
                    numStr.append(expression.charAt(i++));
                }
                numbers.push(Double.parseDouble(numStr.toString()));
                continue;
            }

            // 处理运算符
            if (isOperator(c)) {
                // 处理运算符优先级
                while (!operators.isEmpty() && hasPrecedence(c, operators.peek())) {
                    numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
                }
                operators.push(c);
                i++;
                continue;
            }

            // 处理括号
            if (c == '(') {
                operators.push(c);
                i++;
                continue;
            }

            if (c == ')') {
                // 计算括号内的表达式
                while (!operators.isEmpty() && operators.peek() != '(') {
                    numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
                }
                operators.pop(); // 弹出'('
                i++;
                continue;
            }

            throw new IllegalArgumentException("无效字符: '" + c + "'");
        }

        // 处理剩余运算符
        while (!operators.isEmpty()) {
            numbers.push(applyOperation(operators.pop(), numbers.pop(), numbers.pop()));
        }

        if (numbers.size() != 1) {
            throw new IllegalArgumentException("表达式格式错误");
        }

        return numbers.pop();
    }

    private boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    private boolean hasPrecedence(char op1, char op2) {
        if (op2 == '(') return false;
        return (op1 != '*' && op1 != '/') || (op2 != '+' && op2 != '-');
    }

    private double applyOperation(char op, double b, double a) {
        switch (op) {
            case '+': return a + b;
            case '-': return a - b;
            case '*': return a * b;
            case '/':
                if (b == 0) throw new ArithmeticException("除以零");
                return a / b;
            default: throw new IllegalArgumentException("未知运算符: " + op);
        }
    }


    public static void main1(String[] args) {
        CalcController calcController = new CalcController();
        float ret = calcController.calc("12+1");
        System.out.println(ret);
    }
}
